package arrayUtil

import (
	"encoding/json"
	"errors"
	"reflect"
)

func SplitByteArray(data []byte, chunkSize int) [][]byte {
	var chunks [][]byte
	lenData := len(data)
	for i := 0; i < lenData; i += chunkSize {
		end := i + chunkSize
		if end > lenData {
			end = lenData
		}
		chunks = append(chunks, data[i:end])
	}
	return chunks
}

// ArrayChunk 将任意类型的切片按照指定的大小分成子切片
func ArrayChunk(slice interface{}, chunkSize int) (chunks [][]interface{}, err error) {
	s := reflect.ValueOf(slice)
	if s.Kind() != reflect.Slice {
		return nil, errors.New("arrayChunk: slice parameter must be a slice")
	}

	length := s.Len()
	numChunks := (length + chunkSize - 1) / chunkSize // 计算子切片的数量

	chunks = make([][]interface{}, numChunks)
	for i := 0; i < numChunks; i++ {
		start := i * chunkSize
		end := start + chunkSize
		if end > length {
			end = length
		}
		chunks[i] = make([]interface{}, end-start)
		for j := start; j < end; j++ {
			chunks[i][j-start] = s.Index(j).Interface()
		}
	}

	return chunks, nil
}

func ReverseSlice(slice interface{}) {
	// 获取切片的长度
	length := len(slice.([]interface{}))
	// 反转切片
	for i, j := 0, length-1; i < j; i, j = i+1, j-1 {
		slice.([]interface{})[i], slice.([]interface{})[j] = slice.([]interface{})[j], slice.([]interface{})[i]
	}
}

func IsExistsItem(value interface{}, array interface{}) bool {
	switch reflect.TypeOf(array).Kind() {
	case reflect.Slice:
		s := reflect.ValueOf(array)
		for i := 0; i < s.Len(); i++ {
			if reflect.DeepEqual(value, s.Index(i).Interface()) {
				return true
			}
		}
	default:
		return false
	}
	return false
}

// ConvertToAnySlice 泛型转换函数
func ConvertToAnySlice[T any](data []T) []any {
	result := make([]any, len(data))
	for i, v := range data {
		result[i] = v
	}
	return result
}

// ConvertFormMapArray  表单的 map或者数组 都转为数组
func ConvertFormMapArray[T any](input []T) ([]string, error) {
	var result []string
	if input == nil || len(input) == 0 {
		return result, nil
	}
	for _, item := range input {
		// Convert item to JSON string first
		jsonStr, err := json.Marshal(item)
		if err != nil {
			return nil, err
		}
		// Try to unmarshal as map
		var m map[string]string
		if err := json.Unmarshal(jsonStr, &m); err == nil {
			// If it's a map, extract values
			for _, v := range m {
				result = append(result, v)
			}
		} else {
			// If not a map, use the original value
			result = append(result, string(jsonStr))
		}
	}
	return result, nil
}
